FormCKEditor   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 111
c 0
b 0
f 0
dl 0
loc 194
rs 9.52
wmc 36

7 Functions

Rating   Name   Duplication   Size   Complexity  
A constructor 0 6 1
C connectElFinder 0 50 9
A createCustomButtons 0 9 3
A addCustomButton 0 10 4
C connectRichFilemanager 0 50 9
A replaceTextArea 0 16 4
B load 0 13 6
1
/** global: displayJSError */
2
/** global: CKEDITOR */
3
4
/**
5
 * Class to load, configure the CKEditor and connect to Rich Filemanager
6
 * if available.
7
 */
8
class FormCKEditor
9
{
10
    /**
11
     * Constructor get the configuration passed from PHP.
12
     */
13
    constructor(config, editor)
14
    {
15
        this.editor = editor;
16
        this.config = config;
17
        this.oEditor = null;
18
    }
19
    
20
    /**
21
     * Load the CKEditor:
22
     * - replace the textarea and pass option from PHP configuration
23
     * - create custom buttons if specified
24
     * - set if data (content) if comes through the PHP options
25
     * - connect to Rich Filemanager if configured
26
     */
27
    load()
28
    {
29
        this.replaceTextArea();
30
        this.createCustomButtons();
31
        if (this.config.CKEditor.editorData !== undefined) {
32
            this.oEditor.setData(this.config.CKEditor.editorData);
33
        }
34
        if (this.config.RichFilemanager !== undefined) {
35
            this.editor.on('dialogDefinition', (event) => {this.connectRichFilemanager(event);});
36
        } else if (this.config.elFinder !== undefined) {
37
            this.editor.on('dialogDefinition', (event) => {this.connectElFinder(event);});
38
        }
39
    }
40
    
41
    /**
42
     * Replace the textarea and pass option from PHP configuration.
43
     * Dimensions of the textarea are saved and set in the 'instanceReady' event to the created editor
44
     */
45
    replaceTextArea()
46
    {
47
        var oTA = document.getElementById(this.config.CKEditor.editorID);
48
        if (!oTA) {
49
            if (typeof displayJSError === "function") {
50
                displayJSError('Element [' + this.config.CKEditor.editorID + 'to be replaced by CKEditor not exists!', 'error');
51
            }
52
            return;
53
        }
54
        // get initial size of textarea to replace
55
        var iHeight = oTA.offsetHeight;
56
        var iWidth = oTA.offsetWidth;
57
        this.oEditor = this.editor.replace(this.config.CKEditor.editorID, this.config.CKEditor.editorOptions);
58
        // resize to desired size
59
        this.oEditor.on('instanceReady', function(event) {event.editor.resize(iWidth, iHeight);});
60
    }
61
62
    /**
63
     * create custom buttons.
64
     */
65
    createCustomButtons()
66
    {
67
        if (Array.isArray(this.config.CKEditor.customButtons)) {
68
            let length = this.config.CKEditor.customButtons.length;
69
            for (let i = 0; i < length; i++) {
70
                this.addCustomButton(this.config.CKEditor.customButtons[i]);
71
            }
72
        }
73
    }
74
    
75
    /**
76
     * add the custom button.
77
     * Button and command are only added, if the specified handler is defined.
78
     */
79
    addCustomButton(btn)
80
    {
81
        var exec = window[btn.func];
82
        if (typeof exec === "function") {
83
            this.oEditor.addCommand('cmd_' + btn.func, {exec: function(oEditor) {window[btn.func](oEditor);}});
84
            this.oEditor.ui.addButton(btn.func, {label: btn.name, command: 'cmd_' + btn.func, icon: btn.icon});
85
        } else if (typeof displayJSError === "function") {
86
            displayJSError('Handler for Custom Button [' + btn.func + '] is not defined!', 'error');
87
        }
88
    }
89
90
    /**
91
     * Connect to Rich Filemanager.
92
     * The code from the Rich Filemanager example is modified
93
     * - jQuery code is replaced by plain javascript
94
     * - dependen on the dialog/page (link, image, image-link) different folder to
95
     *   expand are set.
96
     */
97
    connectRichFilemanager(event)
98
    {
99
        var editor = event.editor;
100
        var dialogDefinition = event.data.definition;
101
        var dialogName = event.data.name;
102
        var cleanUpFuncRef = this.editor.tools.addFunction(function () {
103
            let oIFrame = document.getElementById('fm-iframeCKE');
104
            if (oIFrame) {
105
                oIFrame.remove();
106
            }
107
            document.body.style.overflowY = 'scroll';
108
        });
109
            
110
        var tabCount = dialogDefinition.contents.length;
111
        for (var i = 0; i < tabCount; i++) {
112
            var dialogTab = dialogDefinition.contents[i];
113
            if (!(dialogTab && typeof dialogTab.get === 'function')) {
114
                continue;
115
            }
116
                
117
            var browseButton = dialogTab.get('browse');
118
            if (browseButton !== null) {
119
                browseButton.hidden = false;
120
                var params = 
121
                    '?CKEditorFuncNum=' + this.editor.instances[event.editor.name]._.filebrowserFn +
122
                    '&CKEditorCleanUpFuncNum=' + cleanUpFuncRef +
123
                    '&langCode=' + this.config.RichFilemanager.language +
124
                    '&CKEditor=' + event.editor.name;
125
                    
126
                if (dialogName == 'link') {
127
                    params += '&expandedFolder=' + this.config.RichFilemanager.expandFolder.browseLinkURL;
128
                } else if (dialogTab.id == 'info') {
129
                    params += '&expandedFolder=' + this.config.RichFilemanager.expandFolder.browseImageURL;
130
                } else {
131
                    params += '&expandedFolder=' + this.config.RichFilemanager.expandFolder.browseImageLinkURL;
132
                }
133
                browseButton.filebrowser.rfm_path = this.config.RichFilemanager.Path + params;
134
                browseButton.onClick = function (dialog) {
135
                    editor._.filebrowserSe = this;
136
                    
137
                    let oIFrame = document.createElement('iframe');
138
                    oIFrame.id = 'fm-iframeCKE';
139
                    oIFrame.className = 'fm-modal';
140
                    oIFrame.src = dialog.sender.filebrowser.rfm_path;
141
                    document.body.append(oIFrame);
142
                    document.body.style.overflowY = 'hidden';
143
                }
144
            }
145
        }
146
    }
147
148
    /**
149
     * Connect to elFinder.
150
     */
151
    connectElFinder(event)
152
    {
153
        var editor = event.editor;
154
        var dialogDefinition = event.data.definition;
155
        var dialogName = event.data.name;
156
        var cleanUpFuncRef = this.editor.tools.addFunction(function () {
157
            let oIFrame = document.getElementById('fm-iframeCKE');
158
            if (oIFrame) {
159
                oIFrame.remove();
160
            }
161
            document.body.style.overflowY = 'scroll';
162
        });
163
            
164
        var tabCount = dialogDefinition.contents.length;
165
        for (var i = 0; i < tabCount; i++) {
166
            var dialogTab = dialogDefinition.contents[i];
167
            if (!(dialogTab && typeof dialogTab.get === 'function')) {
168
                continue;
169
            }
170
                
171
            var browseButton = dialogTab.get('browse');
172
            if (browseButton !== null) {
173
                browseButton.hidden = false;
174
                var params = 
175
                    '?CKEditorFuncNum=' + this.editor.instances[event.editor.name]._.filebrowserFn +
176
                    '&CKEditorCleanUpFuncNum=' + cleanUpFuncRef +
177
                    '&langCode=' + this.config.elFinder.language +
178
                    '&CKEditor=' + event.editor.name;
179
                    
180
                if (dialogName == 'link') {
181
                    params += '&expandedFolder=' + this.config.elFinder.expandFolder.browseLinkURL;
182
                } else if (dialogTab.id == 'info') {
183
                    params += '&expandedFolder=' + this.config.elFinder.expandFolder.browseImageURL;
184
                } else {
185
                    params += '&expandedFolder=' + this.config.elFinder.expandFolder.browseImageLinkURL;
186
                }
187
                browseButton.filebrowser.elf_path = this.config.elFinder.Path + params;
188
                browseButton.onClick = function (dialog) {
189
                    editor._.filebrowserSe = this;
190
                    
191
                    let oIFrame = document.createElement('iframe');
192
                    oIFrame.id = 'fm-iframeCKE';
193
                    oIFrame.className = 'fm-modal';
194
                    oIFrame.src = dialog.sender.filebrowser.elf_path;
195
                    document.body.append(oIFrame);
196
                    document.body.style.overflowY = 'hidden';
197
                }
198
            }
199
        }
200
    }
201
}
202